<?php
namespace app\admin\model;
use think\Db;
use think\facade\Config;
use think\Model;
use think\model\concern\SoftDelete;

/**
 * 后台渠道模型
 * @package app\admin\model
 */
class Channel extends Model {
	// 设置当前模型对应的完整数据表名称
	protected $table = 'bus_channel';
	// 开启自动写入时间戳字段
	protected $autoWriteTimestamp = 'datetime';
	protected $dateFormat         = 'Y-m-d H:i:s';
	use SoftDelete;
	protected $deleteTime = 'delete_time';

	protected $observerClass = 'app\admin\event\DeleteCache';

	public function searchOffRedisAttr($query, $value, $data) {
		if (isMmsOrSms()) {
			$query->where('off_redis', '=', 0);
		}

	}
	//分页获取所有渠道信息
	public function getAll($request, $field = '*', $where = '') {

		return $this::withSearch(['off_redis'])
			->alias('bc')
			->field($field)
			->where($where)
			->join('bus_channel_cmpp bcc', 'bcc.sp_id = bc.channel_id', 'LEFT')
			->join('bus_channel_key key', 'bc.channel_id = key.cid', 'LEFT')
			->paginate($request['limit'], false, $request)
			->each(function ($item, $key) {

				$item->company_name = $item->channel_id . '/' . $item->company_name;

				if ($item->user_name || $item->channel_phone) {
					$item->user_name = $item->user_name . '/' . $item->channel_phone;
				}

				switch ($item->status) {
				case '1':
					$item->status_ = '<span class="layui-badge layui-bg-green status-qy">开启</span>';
					break;

				default:
					$item->status_ = '<span class="layui-badge status-jy">禁用</span>';
					break;
				}

				switch ($item->level) {
				case '1':
					$item->level_ = '代理账号';
					break;
				case '2':
					$item->level_ = '集团账号';
					break;
				case '3':
					$item->level_ = '普通账号';
					break;
				case '4':
					$item->level_ = '集团账号';
					break;
				case '5':
					$item->level_ = '普通账号';
					break;

				default:
					$item->level_ = '';
					break;
				}

				if (session('user_type') == 'admin') {
					$item->p_id = $item->p_id . '/' . $item->agent_id;
					switch ($item->check_plat_sign) {
					case '1':
						$item->check_plat_sign = '<span class="layui-badge layui-bg-green status-qy">开启</span>';
						break;

					default:
						$item->check_plat_sign = '<span class="layui-badge status-jy">禁用</span>';
						break;
					}

					switch ($item->off_ip) {
					case '0':
						$item->off_ip_ = '<span class="layui-badge layui-bg-green">开启</span>';
						break;
					case '1':
						$item->off_ip_ = '<span class="layui-badge">禁用</span>';
						break;
					default:
						$item->off_ip_ = '未知配置';
						break;
					}
					switch ($item->onoff) {
					case '1':
						$item->onoff_ = '<span class="layui-badge layui-bg-green status-wlj">通讯中</span>';
						break;
					case '0':
						$item->onoff_ = '<span class="layui-badge status-txz">未连接</span>';
						break;
					default:
						$item->onoff_ = '';
						break;
					}

					switch ($item->war_onoff) {
					case '1':
						$item->war_onoff_ = '<span class="layui-badge layui-bg-green">开启</span>';
						break;
					case '0':
						$item->war_onoff_ = '<span class="layui-badge">禁用</span>';
						break;
					default:
						$item->war_onoff_ = '';
						break;
					}
					switch ($item->black_off) {
					case '1':
						$item->black_off = '<span class="layui-badge layui-bg-green">开启</span>';
						break;
					case '0':
						$item->black_off = '<span class="layui-badge">禁用</span>';
						break;
					default:
						$item->black_off = '';
						break;
					}
					switch ($item->channel_black_off) {
					case '1':
						$item->channel_black_off = '<span class="layui-badge layui-bg-green">开启</span>';
						break;
					case '0':
						$item->channel_black_off = '<span class="layui-badge">禁用</span>';
						break;
					default:
						$item->channel_black_off = '';
						break;
					}

					switch ($item->more_ip) {
					case '1':
						$item->more_ip_ = '<span class="layui-badge-dot layui-bg-green"></span> - ' . $item['connection'];
						break;
					case '0':
						$item->more_ip_ = '<span class="layui-badge-dot"></span> - ' . $item['connection'];
						break;
					default:
						$item->more_ip_ = '';
						break;
					}
				} else {
					//代理才开放key
					if (session('channel_level') != 1) {
						$item->cid_key = '';
					}
				}

				if (isset($item->acchannel_id) && $item->acchannel_id != '') {
					$item->user_name     = '******';
					$item->channel_phone = '******';
				}
				// if (session('user_type') == 'channel') {

				//     if (session('channel_type') != 'THHP') {

				//         $item->upstream_url = '';
				//     }
				// }

			});
	}

	//渠道开关
	public function openOrClose($channel_id, $status) {
		trace(session('username') . '把渠道id为' . $channel_id . '的开启状态改为了' . $status, 'info');
		return $this::isUpdate(true)->save(['status' => $status], ['channel_id' => $channel_id]);
	}

	//添加渠道
	public function addChannel($data) {
		$data['update_user'] = session('username');
		$data['create_user'] = session('username');
		return $this::isUpdate(false)->allowField(true)->save($data);
	}

	//验证ip是否正确
	public function checkIp($data, $id) {
		if (!isset($data['ip'])) {
			$ip = str_replace('，', ',', $data);
			$ip = explode(',', $ip);
		} else {
			$ip = str_replace('，', ',', $data['ip']);
			$ip = explode(',', $ip);
		}

		$pattern = "/^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$/";
		foreach ($ip as $k => $v) {
			if (!preg_match($pattern, $v)) {
				return false;
			}
		}
		foreach ($ip as $val) {
			$row = [
				'channel_ip' => $val,
				'channel_id' => $id,
			];
			if (isset($data['client_ip'])) {
				$row['client_ip'] = $data['client_ip'];
			}

			if (!Db::name('bus_channel_ip')->where($row)->find()) {
				Db::name('bus_channel_ip')->insert($row);
			} else {
				Db::name('bus_channel_ip')->where('channel_id', $id)->update(['ip_status' => 1]);
			}
		}
		return true;

	}

	//获取渠道信息
	public function getChannel($channelId) {
		$data['channel_id'] = $channelId;
		return $this::get($data)->toArray();
	}

	//更新渠道信息
	public function updChannel($data) {
		return $this::isUpdate(true)->allowField(true)->where(['channel_id' => $data['cid'], 'p_id' => session('relate_id')])->save($data);
	}

	//用于黑名单
	public function getAllChannel() {
		$fields = 'channel_id,company_name';
		return $this::field($fields)->select()->toArray();
	}

	/**
	 * 充值余额
	 * @Author   lf
	 * @DateTime 2018-06-29T16:43:52+0800
	 * @param    [type]                   $channel_id  [渠道id]
	 * @param    [type]                   $rechargenum [充值金额]
	 * @param    [type]                   $remarks     [充值备注]
	 */
	public function setSmsBalance($channel_id, $rechargenum, $remarks) {
		if (empty($channel_id) || empty($rechargenum)) {
			trace(session('username') . '充值失败：接收到空的参数', 'error');
			echo "充值失败";
			return false;
		}

		//redis添加
		$isRdis = false;

		// 启动事务
		Db::startTrans();
		try {
			$channel = $this::get(['channel_id' => $channel_id]);
			//获取单价
			$sms_price = $channel->sms_price;
			//单价小于等于0操作失败
			if ($sms_price <= 0) {
				echo "单价不能小于等于0";
				Db::rollback();
				return false;
			}
			//新余额
			$newoevrplus = $channel->oevrplus + $rechargenum;
			//调整前数目
			$note_num_ago = floor($channel->oevrplus / $sms_price);
			//调整后数目
			$note_num_now = floor($newoevrplus / $sms_price);
			//调整数目
			$operation_num = $note_num_now - $note_num_ago;
			//更新余额
			Db::table('bus_channel')->where('channel_id', $channel_id)->update(['oevrplus' => $newoevrplus]);

			$data['channel_id']      = $channel_id;
			$data['note_num_ago']    = $note_num_ago;
			$data['note_num_now']    = $note_num_now;
			$data['operation_type']  = '1'; //1充值
			$data['operation_num']   = $operation_num;
			$data['operation_fee']   = $rechargenum; //操作金额
			$data['account_balance'] = $newoevrplus;
			$data['remarks']         = $remarks;
			$data['operation_user']  = session('user_id');
			$data['operation_time']  = date('Y-m-d H:i:s');
			//添加记录
			Db::table('bus_record')->insert($data);

			trace('渠道：' . $channel_id . '充值短信 ' . $operation_num . '条,单价(' . $sms_price . ')，余额由' . $channel->oevrplus . '变' . $newoevrplus . '；操作人：' . session('username'), 'info');
			echo "success";
			// 提交事务
			Db::commit();
			$isRdis = true;
		} catch (\Exception $e) {
			// 回滚事务
			Db::rollback();
			trace(session('username') . '-渠道：' . $channel_id . '充值失败：执行错误回滚事务' . $e, 'error');
			echo "充值失败,服务器繁忙";
			return false;
		}

		if ($isRdis) {
			//redis添加
			//$this->redIscrl('add', $channel_id, bcmul($rechargenum, 100000));

			try {
				Db::table('war_user')->where('user_id', $channel_id)->update(['war_count_count' => 0]);
			} catch (\Exception $e) {

			}
		}

		return true;
	}

	/**
	 * 调价
	 * @Author   lf
	 * @DateTime 2018-06-29T16:43:40+0800
	 * @param    [type]                   $channel_id [渠道id]
	 * @param    [type]                   $newprice   [新单价]
	 * @param    [type]                   $remarks    [备注]
	 * @return   [type]                               [description]
	 */
	public function adjustSmsBalance($channel_id, $newprice, $remarks) {
		if (empty($channel_id) || empty($newprice)) {
			trace(session('username') . '调价失败：接收到空的参数', 'error');
			echo "调价失败";
			return;
		}
		if ($newprice <= 0) {echo "不能输入小于等于0";return;}

		// 启动事务
		Db::startTrans();
		try {
			$channel = $this::get(['channel_id' => $channel_id]);
			//不能相同价格
			if ($newprice == $channel['sms_price']) {
				echo "不能输入相同的价格";
				Db::rollback();
				exit;
			}
			//调整前数目
			$note_num_ago = floor($channel->oevrplus / $channel['sms_price']);
			//调整后数目
			$note_num_now = floor($channel->oevrplus / $newprice);
			//调整数目
			$operation_num = $note_num_now - $note_num_ago;
			//更新单价
			Db::table('bus_channel')->where('channel_id', $channel_id)->update(['sms_price' => $newprice]);
			//更新该渠道下的所有子渠道单价
			Db::table('bus_channel')->where('p_id', $channel_id)->update(['sms_price' => $newprice]);
			$data['channel_id']      = $channel_id;
			$data['note_num_ago']    = $note_num_ago;
			$data['note_num_now']    = $note_num_now;
			$data['operation_type']  = '2'; //2调价
			$data['operation_num']   = $operation_num;
			$data['account_balance'] = $channel->oevrplus;
			$data['remarks']         = $remarks;
			$data['operation_user']  = session('user_id');
			$data['operation_time']  = date('Y-m-d H:i:s');
			//添加记录
			Db::table('bus_record')->insert($data);

			// 提交事务
			Db::commit();

			trace('渠道：' . $channel_id . '调价由' . $channel['sms_price'] . '改' . $newprice . '操作人：' . session('username'), 'info');
			deleteCache('CHANNEL');
			echo "success";
		} catch (\Exception $e) {
			// 回滚事务
			Db::rollback();
			trace(session('username') . '调价将渠道：' . $channel_id . '由' . $channel['sms_price'] . '改' . $newprice . ' -失败：执行错误回滚事务' . $e, 'error');
			echo "调价失败,服务器繁忙";
		}

	}

	/**
	 * 余额转移
	 * @Author   lf
	 * @DateTime 2018-07-02T10:23:05+0800
	 * @param    [type]                   $channel_id       [渠道id]
	 * @param    [type]                   $channel_id_shift [转移目标]
	 * @param    [type]                   $num_shift        [转移数目]
	 * @param    [type]                   $remarks          [备注]
	 * @return   [type]                                     [description]
	 */
	public function shiftSmsBalance($channel_id, $channel_id_shift, $num_shift, $remarks) {
		if (empty($channel_id) || empty($channel_id_shift) || empty($num_shift)) {
			trace(session('username') . '转移余额失败：接收到空的参数', 'error');
			echo "调价失败";
			return;
		}
		if ($num_shift <= 0) {echo "非法操作";exit;}

		$isRdis    = false;
		$isRdisdel = false;

		// 启动事务
		Db::startTrans();
		try {
			$channel       = $this->where(['channel_id' => $channel_id])->find();
			$channel_shift = $this->where(['channel_id' => $channel_id_shift])->find();

			//调整余额
			$oevrplus_shift = $channel['sms_price'] * $num_shift;
			//调整前数目
			$note_num_ago = floor($channel['oevrplus'] / $channel['sms_price']);
			//判断
			if ($num_shift > $note_num_ago) {
				echo "余额不足" . $num_shift . "条";
				Db::rollback();exit;}
			if ($channel['sms_price'] != $channel_shift['sms_price']) {
				echo "单价不统一";
				Db::rollback();exit;}

			//redis减
			//$this->redIscrl('del', $channel_id, bcmul($oevrplus_shift, 100000));
			$isRdisdel = true;

			//减余额
			Db::table('bus_channel')->where('channel_id', $channel_id)->update(['oevrplus' => $channel['oevrplus'] - $oevrplus_shift]);
			$data['channel_id']      = $channel_id;
			$data['note_num_ago']    = $note_num_ago; //调整前数目
			$data['note_num_now']    = $note_num_ago - $num_shift; //调整后数目
			$data['operation_type']  = '3'; //3转移余额
			$data['operation_num']   = -$num_shift;
			$data['operation_fee']   = $oevrplus_shift; //操作金额
			$data['account_balance'] = $channel['oevrplus'] - $oevrplus_shift;
			$data['remarks']         = $remarks;
			$data['operation_user']  = session('user_id');
			$data['operation_time']  = date('Y-m-d H:i:s');
			//添加记录
			Db::table('bus_record')->insert($data);

			//转移目标调整前数目
			$note_num_ago1 = floor($channel_shift['oevrplus'] / $channel['sms_price']);
			//加余额
			Db::table('bus_channel')->where('channel_id', $channel_id_shift)->update(['oevrplus' => $channel_shift['oevrplus'] + $oevrplus_shift]);

			$data1['channel_id']      = $channel_id_shift;
			$data1['note_num_ago']    = $note_num_ago1; //调整前数目
			$data1['note_num_now']    = $note_num_ago1 + $num_shift; //调整后数目
			$data1['operation_type']  = '3'; //3转移余额
			$data1['operation_num']   = $num_shift;
			$data1['operation_fee']   = $oevrplus_shift; //操作金额
			$data1['account_balance'] = $channel_shift['oevrplus'] + $oevrplus_shift;
			$data1['remarks']         = $remarks;
			$data1['operation_user']  = session('user_id');
			$data1['operation_time']  = date('Y-m-d H:i:s');
			//添加记录
			Db::table('bus_record')->insert($data1);

			$log = '渠道：' . $channel_id . '向渠道' . $channel_id_shift . ' 转移短信条数' . $num_shift . '，操作人：' . session('username') . "\r\n";
			$log .= '渠道：' . $channel['company_name'] . '(' . $channel_id . ')的余额由' . $channel['oevrplus'] . '变为' . ($channel['oevrplus'] - $oevrplus_shift) . "\r\n";
			$log .= '渠道：' . $channel_shift['company_name'] . '(' . $channel_id_shift . ')的余额由' . $channel_shift['oevrplus'] . '变为' . ($channel_shift['oevrplus'] + $oevrplus_shift) . "\r\n";
			trace($log, 'info');
			echo "success";
			// 提交事务
			Db::commit();
			$isRdis = true;
		} catch (\Exception $e) {
			if ($isRdisdel) {
				//redis添加
				//$this->redIscrl('add', $channel_id, bcmul($oevrplus_shift, 100000));
			}
			// 回滚事务
			Db::rollback();
			trace(session('username') . '转移余额由' . $channel_id . '向' . $channel_id_shift . '转移余额' . $num_shift . ' -失败：执行错误回滚事务' . $e, 'error');
			echo "转移失败";
			exit;
		}

		if ($isRdis) {
			//$this->redIscrl('add', $channel_id_shift, bcmul($oevrplus_shift, 100000));
		}
	}

	/**
	 * 退款
	 * @Author   lf
	 * @DateTime 2018-07-03T14:52:21+0800
	 * @param    [type]                   $channel_id [渠道id]
	 * @param    [type]                   $refundnum  [退款金额]
	 * @param    [type]                   $remarks    [备注]
	 */
	public function setBalanceRefund($channel_id, $refundnum, $remarks) {
		if (empty($channel_id) || empty($refundnum)) {
			trace(session('username') . '退款失败：接收到空的参数', 'error');
			echo "退款失败";
			return false;
		}

		//redis减
		//$this->redIscrl('del', $channel_id, bcmul($refundnum, 100000));

		// 启动事务
		Db::startTrans();
		try {
			$channel = $this::get(['channel_id' => $channel_id]);
			//获取单价
			$sms_price = $channel->sms_price;
			//单价小于等于0操作失败
			if ($sms_price <= 0) {
				echo "单价不能小于等于0";
				trace("单价不能小于等于0", 'info');
				Db::rollback();
				//$this->redIscrl('add', $channel_id, bcmul($refundnum, 100000));
				return false;
			}
			if ($refundnum > $channel->oevrplus) {
				echo "该渠道余额不足" . $refundnum . '元';
				trace("该渠道余额不足" . $refundnum . '元', 'info');
				Db::rollback();
				//$this->redIscrl('add', $channel_id, bcmul($refundnum, 100000));
				return false;
			}
			//新余额
			$newoevrplus = $channel->oevrplus - $refundnum;
			//调整前数目
			$note_num_ago = floor($channel->oevrplus / $sms_price);
			//调整后数目
			$note_num_now = floor($newoevrplus / $sms_price);
			//调整数目
			$operation_num = $note_num_now - $note_num_ago;
			//更新余额
			Db::table('bus_channel')->where('channel_id', $channel_id)->update(['oevrplus' => $newoevrplus]);

			$data['channel_id']      = $channel_id;
			$data['note_num_ago']    = $note_num_ago;
			$data['note_num_now']    = $note_num_now;
			$data['operation_type']  = '4'; //4退款
			$data['operation_num']   = $operation_num;
			$data['operation_fee']   = $refundnum; //操作金额
			$data['account_balance'] = $newoevrplus;
			$data['remarks']         = $remarks;
			$data['operation_user']  = session('user_id');
			$data['operation_time']  = date('Y-m-d H:i:s');
			//添加记录
			Db::table('bus_record')->insert($data);

			trace('渠道：' . $channel_id . '退款短信 ' . $operation_num . '条,单价(' . $sms_price . ')，余额由' . $channel->oevrplus . '变' . $newoevrplus . '；操作人：' . session('username'), 'info');
			echo "success";
			// 提交事务
			Db::commit();
		} catch (\Exception $e) {
			// 回滚事务
			Db::rollback();
			//redis加
			// //$this->redIscrl('add', $channel_id, bcmul($refundnum, 100000));
			trace(session('username') . '-渠道：' . $channel_id . '退款失败：执行错误回滚事务' . $e, 'error');
			echo "退款失败,服务器繁忙";
			return false;
		}

		return true;
	}

	//查询顶级渠道下的所有子渠道
	public function getChannelTree($userChannel) {
		$channelArr = $this::field('channel_id')->where(['p_id' => $userChannel])->select();
		$arr        = [];
		if ($channelArr) {
			foreach ($channelArr as $k => $v) {
				$arr[] = $v['channel_id'];
			}
		}
		return $arr;
	}

	/**
	 * redis原子操作增删
	 * @Author   lf
	 * @DateTime 2019-07-12T10:02:16+0800
	 * @param    [type]                   $sem [description]
	 * @param    [type]                   $num [description]
	 * @return   [type]                        [description]
	 */
	public function redisCrl($sem, $cid, $num) {
		// $ZD_REDIS_CONFIG = Config::get('ZD_REDIS_CONFIG');
		// //连接本地的 Redis 服务
		// $redis = new \Redis();
		// $redis->connect($ZD_REDIS_CONFIG['IP'], $ZD_REDIS_CONFIG['PORT']);
		// $redis->auth($ZD_REDIS_CONFIG['PASSWORD']); //密码
		// $redis->select(4);

		// $renum = $redis->get('P_' . $cid);

		// if ($renum == '' || $renum == null) {
		// 	trace('渠道' . $cid . '的之前的金额是：' . $renum . '，终止添加redis');
		// 	return;
		// }
		// switch ($sem) {
		// case 'add':

		// 	trace('渠道' . $cid . '的Redis增加金额（单位 里）：' . $num);

		// 	$redisnum = $redis->Incr('P_' . $cid, $num);

		// 	trace('渠道' . $cid . '的Redis增加金额后的数字：' . $redisnum);
		// 	//
		// 	return $redisnum;
		// 	break;
		// case 'del':

		// 	trace('渠道' . $cid . '的Redis减去金额（单位 里）：' . $num);

		// 	$redisnum = $redis->Decr('P_' . $cid, $num);

		// 	trace('渠道' . $cid . '的Redis减去金额后的数字：' . $redisnum);

		// 	return $redisnum;
		// 	break;

		// default:
		// 	exit('无法识别操作');
		// 	break;
		// }

	}
	//查询该渠道是否为一级渠道，或者是4级集团账号
	public static function checkChannelAndChild($channelId = null) {
		$channelInfo = self::where('channel_id', $channelId)->find();
		if ($channelInfo) {
			switch ($channelInfo['level']) {
			case '1': //代理用户
				return self::where('p_id', $channelId)->where('level', 2)->column('channel_id');
				break;
			case '4': //集团用户

				break;
			default:
				# code...
				break;
			}
		}
	}
}
